package org.snail.proxy.client;

import com.google.protobuf.ByteString;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snail.proxy.client.config.AgentConfig;
import org.snail.proxy.proto.Client;
import org.snail.proxy.proto.HttpMessage;
import org.snail.proxy.proto.MessageId;
import org.snail.proxy.proto.Packet;
import org.snail.proxy.proto.ProxyMessage;

public class LocalHTTPClient implements Client {
    private static final Logger log = LoggerFactory.getLogger(LocalHTTPClient.class);

    private final Channel proxyChannel;
    private final String id;
    private final String domain;

    public LocalHTTPClient(Channel proxyChannel, String id, AgentConfig agentConfig) {
        this.proxyChannel = proxyChannel;
        this.id = id;
        domain = (agentConfig.isSsl() ? "https" : "http") + "://" + agentConfig.getLocalIp() + ":" + agentConfig.getLocalPort();
    }

    @Deprecated
    @Override
    public void connect(String ip, int port) {}

    @Deprecated
    @Override
    public void disconnect() {}

    @Override
    public void sendMessage(Object message) {
        if (message instanceof byte[]) {
            try {
                HttpMessage httpMessage = HttpMessage.parseFrom((byte[]) message);
                String response;
                switch (httpMessage.getMethod()) {
                case GET:
                    response = HttpClient.get(domain + httpMessage.getUri(), httpMessage.getHeadersMap());
                    break;
                case POST:
                    response = HttpClient.post(domain + httpMessage.getUri(), httpMessage.getHeadersMap(), new String(httpMessage.getBody().toByteArray()));
                    break;
                case PUT:
                    response = HttpClient.put(domain + httpMessage.getUri(), httpMessage.getHeadersMap(), new String(httpMessage.getBody().toByteArray()));
                    break;
                case DELETE:
                    response = HttpClient.delete(domain + httpMessage.getUri(), httpMessage.getHeadersMap());
                    break;
                default:
                    response = "un know http method: " + httpMessage.getMethod();
                }
                ProxyMessage resp = ProxyMessage.newBuilder().setId(id).setData(ByteString.copyFrom(response.getBytes())).build();
                proxyChannel.writeAndFlush(new Packet((byte) 0, MessageId.PROXY_MESSAGE_VALUE, resp.toByteArray()));
                log.info("Local http server message: {}[{}].", id, response);
            } catch (Exception e) {
                log.error("sendMessage Exception: ", e);
            }
        }
    }

    @Override
    public boolean isConnected() {
        return true;
    }
}
